/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package net.worlds.lua.metatable;

import java.util.logging.Level;
import java.util.logging.Logger;
import net.worlds.WorldsException;
import net.worlds.Main;
import net.worlds.ObjectList;
import net.worlds.object.GameObject;
import se.krka.kahlua.vm.JavaFunction;
import se.krka.kahlua.vm.LuaCallFrame;


public class GameObjectMetatable {
    public static class GameObjectTostring implements JavaFunction
    {

        public int call(LuaCallFrame callFrame, int nArguments) {
            callFrame.push(callFrame.get(0).toString());
            return 1;
        }

    }
    public static class GameObjectIndex implements JavaFunction
    {
        public int call(LuaCallFrame callFrame, int nArguments) {
            synchronized(callFrame.thread.state.getEnvironment())
            {
                try {
                    GameObject obj = (GameObject) callFrame.get(0);
                    String k = (String) callFrame.get(1);
                    if(obj.hasFunction(k))
                        callFrame.push(obj.getFunction(k));
                    else if (obj.hasEvent(k))
                        callFrame.push(obj.getEvent(k));
                    else if (obj.hasChild(k))
                        callFrame.push(obj.getChild(k));
                    else
                    {
                        try {
                            Object v = obj.getProp(k);
                            if(obj.tempProperties.containsKey(k))
                                callFrame.push(obj.tempProperties.get(k));
                            else
                                callFrame.push(v);
                        } catch (WorldsException ex) {
                            throw new RuntimeException(k + " is not a function, child or property of " + obj);
                        }
                    }
                    return 1;
                } catch (Exception ex) {
                    throw new RuntimeException(ex.toString());
                }
            }
        }
        @Override
        public String toString()
        {
            return "Object.newIndex";
        }
    }
    public static class GameObjectNewIndex implements JavaFunction
    {

        public int call(final LuaCallFrame callFrame, int nArguments) {
            synchronized(callFrame.thread.state.getEnvironment())
            {
                final GameObject obj = (GameObject) callFrame.get(0);
                final String k = (String) callFrame.get(1);
                final Object v = callFrame.get(2);
                try
                {
                    obj.getProp(k);
                }
                catch(WorldsException ex)
                {
                    throw new RuntimeException(k+" is not a property of "+obj.getType());
                }
                final Object value;
                if(v instanceof Double)
                {
                    double d = (Double) v;
                    if(ObjectList.getPropDef(obj.getClass().getSimpleName(), k).type == Integer.class)
                    {
                        value = (int) d;
                    }
                    else
                        value = (float) d;
                }
                else if(v instanceof String)
                    value = ((String)v).replace("\\[\\", "[").replace("\\]\\", "]");
                else
                    value = v;
                final Object fValue = value;
                Runnable r = new Runnable()
                {
                    public void run()
                    {
                        try {
                            try
                            {
                                obj.setProp(k, value, true);
                                obj.tempProperties.remove(k);
                            }
                            catch(ClassCastException ex){
                                if(Main.debug)
                                    ex.printStackTrace();
                                System.err.println(callFrame.thread.getStackTrace(callFrame));
                            }
                        } catch (WorldsException ex) {
                            throw new RuntimeException(ex.getError());
                        }
                    }
                };
                if(Thread.currentThread() != Main.mainThread)
                    obj.tempProperties.put(k, value);
                Main.runInMainThread(r);
                return 0;
            }
        }
    }
}
